package lab_14.com.acme.bankapp.domain.bank;

import lab_14.com.acme.bankapp.domain.bank.Exceptions.OverdraftLimitExceededException;

public class CheckingAccount extends AbstractAccount {

	// We don't need an extra entity for overdraft, as negative values of
	// balance can be used
	// to denote overdraft. Not only this rids us of extra variable, it also
	// simplifies logic,
	// which would have to process 2 entities in the other case.

	/**
	 * 
	 */
	private static final long serialVersionUID = -3048883311395377772L;
	private double overdraft_limit;

	public CheckingAccount(double balance, double overdraft_limit)
			throws IllegalArgumentException {
		super(balance);
		this.overdraft_limit = overdraft_limit;
		if (balance < -overdraft_limit) {
			throw new IllegalArgumentException(
					"Balance shouldn't be less than possible overdraft.");
		}
	}

	@Override
	public void withdraw(double amount) throws IllegalArgumentException,
			OverdraftLimitExceededException {
		if (amount < 0) {
			throw new IllegalArgumentException(
					"Amount can only be greater than zero.");
		}
		if (maximumAmountToWithdraw() >= amount) {
			balance -= amount;
		} else {
			throw new OverdraftLimitExceededException(this,
					maximumAmountToWithdraw());
		}
		assert (balance >= -overdraft_limit) : "Overdraft has exceeded overdraft limit";
	}

	@Override
	public double maximumAmountToWithdraw() {
		double value = balance + overdraft_limit;
		return (value >= 0) ? value : 0;
	}

	@Override
	public String toString() {
		StringBuilder builder = new StringBuilder();
		builder.append("---Checking accounts---\n");
		builder.append(String.format("Account id: %1$d\n", getId()));
		builder.append(String.format("Balance: %1$f\n", balance));
		builder.append(String.format("Balance decimal value: %1$d\n",
				decimalValue()));
		builder.append(String
				.format("Overdraft limit: %1$f\n", overdraft_limit));
		builder.append(String.format("Maximum amount to withdraw: %1$f\n",
				maximumAmountToWithdraw()));

		return builder.toString();
	}

	@Override
	public void printAllAccountData() {
		System.out.print(toString());
	}

	@Override
	public String getAccountStreamData() {

		return String.format("accounttype=%s;balance=%s;overdraftlimit=%s;",
				"c", Utils.formatDouble(balance),
				Utils.formatDouble(overdraft_limit));
	}
}
